//=============================================================================
// SentinelWeapon - Interchangeable weapons.
//=============================================================================
class SentinelWeapon extends SentinelUpgrade;

var() float FireRate;
var() sound FireSound;
var() class<Projectile> ProjectileClass;
var() float ProjSpawnOffset; //Forward offset only.
var() float Spread;

var() class<SWeaponAttachment> WeaponAttachmentClass;
var SWeaponAttachment WeaponAttachment;
var() vector WeaponOffset;
var byte HitCount, LastHitCount;

var() class<xEmitter> MuzzleFlashClass;
var xEmitter MuzzleFlash;
var() vector FlashOffset;
var() float FlashScale;
var byte FlashCount, LastFlashCount;

var() float Loudness;

var() int MaxAmmo;
var int AmmoAmount;
var int AmmoPerFire;

var() bool bNoAnim;

var int TeamIndex;

replication
{
	reliable if(Role == ROLE_Authority)
		TeamIndex;

	unreliable if(Role == ROLE_Authority)
		FlashCount, HitCount;
}

//For doing things like setting team coloured projectiles and muzzle flashes.
simulated function SetTeam(){}

function InitFor(Sentinel S)
{
	Super.InitFor(S);

	if(Level.Game.bTeamGame)
		TeamIndex = S.PlayerReplicationInfo.Team.TeamIndex;

	SetTeam();

	if(Level.NetMode != NM_DedicatedServer)
		SetAttachment();
}

simulated function SetAttachment()
{
	if(Sentinel == None)
		return;

	if(WeaponAttachmentClass != None)
	{
		Sentinel.SetBoneScale(0);
		WeaponAttachment = spawn(WeaponAttachmentClass);
		Sentinel.SetBoneScale(0, 0.1, 'bone_cannon');
		Sentinel.AttachToBone(WeaponAttachment, 'bone_cannon');
		WeaponAttachment.SetRelativeLocation(WeaponOffset);
		WeaponAttachment.SetRelativeRotation(rot(0, 0, -16384));
	}
	else
		Sentinel.SetBoneScale(0);
}

//So the Sentinel knows when it can fire.
function float MaxRange()
{
	return 10000;
}

function Projectile FireAt(vector Start, vector BarrelDir, vector Aim)
{
	local Projectile Proj;

	if(AmmoAmount < 1)
		return None;

	AmmoAmount -= AmmoPerFire;

	SetTeam();
	PlaySound(FireSound);
	Proj = Sentinel.Spawn(ProjectileClass, Sentinel,, Start + (BarrelDir * ProjSpawnOffset), rotator(Aim));
	Sentinel.MakeNoise(Loudness);

	if(MuzzleFlashClass != None || !bNoAnim)
	{
		FlashCount++;

		if(Level.NetMode != NM_DedicatedServer)
			FlashMuzzleFlash();
	}

	//Fixes no-instigator bug.
	if(Proj != None)
		Proj.InstigatorController = Sentinel.InstigatorController;

	return Proj;
}

simulated event PostNetReceive()
{
	if(WeaponAttachment == None)
		SetAttachment();
	else if(HitCount != LastHitCount)
	{
		WeaponAttachment.SetOverlayMaterial(Sentinel.DamageOverlay, Sentinel.DamageOverlayTime, false);
		LastHitCount = HitCount;
	}

	if(FlashCount != LastFlashCount)
	{
		SetTeam();
		FlashMuzzleFlash();
		LastFlashCount = FlashCount;
	}
}

simulated function FlashMuzzleFlash()
{
	if(Sentinel == None)
		return;

	if(MuzzleFlash == None && Level.NetMode != NM_DedicatedServer && MuzzleFlashClass != None)
	{
		MuzzleFlash = spawn(MuzzleFlashClass);

		if(WeaponAttachment != None)
			WeaponAttachment.AttachToBone(MuzzleFlash, 'Bone_Flash');
		else
			Sentinel.AttachToBone(MuzzleFlash, 'Bone_Flash');

		MuzzleFlash.SetDrawScale(FlashScale);
		MuzzleFlash.SetRelativeLocation(FlashOffset);
	}

	if(MuzzleFlash != None)
		MuzzleFlash.Trigger(Sentinel, None);

	LastFlashCount = FlashCount;

	if(!bNoAnim)
		Sentinel.PlayAnim('Fire', 1.0, 0.1);
}

function PlayHit()
{
	Super.PlayHit();

	HitCount++;

	if(WeaponAttachment != None)
		WeaponAttachment.SetOverlayMaterial(Sentinel.DamageOverlay, Sentinel.DamageOverlayTime, false);
}

simulated function Destroyed()
{
	Super.Destroyed();

	if(MuzzleFlash != None)
		MuzzleFlash.Destroy();

	if(WeaponAttachment != None)
		WeaponAttachment.Destroy();
}

defaultproperties
{
     UpgradeName="A weapon with no name."
     bFitsCeiling=False
     TransientSoundVolume=0.300000
     bNetNotify=True
}
